﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace ServerCrafter.ClassLibrary
{
    public class Player
    {
        public string Name { get; set; }

        public string Ip { get; set; }

        public string Id { get; set; }

        public string World { get; set; }

        public string RealLifeLocation { get; set; }
    }

    public static class PlayerEvents
    {
        public static readonly List<Player> Players = new List<Player>();
        public static bool RefreshPlayerList;

        public static void Join(string msg)
        {
            Logger.WriteInfo("Player join event has occured. Parsing message for player name, IP, entity ID and in-game world/");
            msg = msg.Split("[INFO]", StringSplitOptions.RemoveEmptyEntries)[1];

            var player = new Player
            {
                Name = msg.Split('[')[0].Trim(),
                Ip = msg.Split("[/", StringSplitOptions.RemoveEmptyEntries)[1].Split("] logged in with entity id ", StringSplitOptions.RemoveEmptyEntries)[0].Split(':')[0],
                Id = msg.Split(" logged in with entity id ", StringSplitOptions.RemoveEmptyEntries)[1].Split(" at ([", StringSplitOptions.RemoveEmptyEntries)[0],
                World = msg.Split(" at ([", StringSplitOptions.RemoveEmptyEntries)[1].Split("] ", StringSplitOptions.RemoveEmptyEntries)[0]
            };
            Logger.WriteInfo("Parsing of player join messege has been completed.");
            Players.Add(player);
            Logger.WriteInfo("Player has been added to player list.");
            RefreshPlayerList = true;
            Logger.WriteInfo("Name: " + player.Name + " IP: " + player.Ip + " ID: " + player.Id + " World: " + player.World);
        }

        public static void Leave(string msg)
        {
            Logger.WriteInfo("Player leave event has occured. Parsing message for player name.");

            msg = msg.Split("[INFO]", StringSplitOptions.RemoveEmptyEntries)[1];

            var name = msg.Split(" lost connection:", StringSplitOptions.RemoveEmptyEntries)[0].Trim();
            Logger.WriteInfo("Parsing of player leave message has been completed. Looking for player in player list.");

            var playerToRemove = Players.Find(player => player.Name == name);
            if (playerToRemove != null)
            {
                Logger.WriteInfo("Player has been found in player list. Removing player from player list.");
                Players.Remove(playerToRemove);
                Logger.WriteInfo("Player has been remove from player list.");
                RefreshPlayerList = true;
            }
            else
            {
                Logger.WriteWarning("Player could not be found in player list. Player could not be removed from player list.");
            }
        }
    }

    public static class Players
    {
        public static ObservableCollection<Player> GetPlayers()
        {
            Logger.WriteInfo("Refreshing player list.");

            PlayerEvents.RefreshPlayerList = false;
            var players = new ObservableCollection<Player>();
            var playerCount = 0;

            foreach (var player in PlayerEvents.Players)
            {
                players.Add(player);
                playerCount++;
                Logger.WriteInfo("Refreshed player #" + playerCount + ": " + player.Name + ".");
            }
            Logger.WriteInfo("Finished refreshing " + playerCount + " players.");
            return players;
        }
    }

    public static class BaseTypesExtensions
    {
        /// <summary>
        /// Returns a string array that contains the substrings in a string that are delimited by a specified string. A parameter specifies whether to return empty array elements.
        /// </summary>
        /// <param name="inputString">The string to be delimited.</param>
        /// <param name="separator">A string that delimits the specified string.</param>
        /// <param name="options"><strong>RemoveEmptyEntries</strong> to omit empty array elements from the array returned;
        /// or <strong>None</strong> to include empty array elements in the array returned.</param>
        /// <returns>
        /// An array whose elements contain the substrings in this string that are delimited by one or more strings in <paramref name="separator"/>. For more information, see the Remarks section.
        /// </returns>
        public static string[] Split(this string inputString, string separator, StringSplitOptions options)
        {
            return inputString.Split(new[] { separator }, options);
        }
    }
}